#include "vtor_string_player.h"

#ifdef __VTOR_STRING_PLAYER__

//https://zhidao.baidu.com/question/1929397911420653787.html
const short VtorStringPlayer_toneArray[] = {0,			// 0静音
		262,  294,  330,  349,  392,  440,  494,		// 1~7低音
		523,  587,  659,  698,  784,  880,  988,		// 8~14中音
		1047, 1175, 1319, 1397, 1568, 1760, 1967		// 15~21高音
};

// 长度分别为 1 2 4 8 16 32 64 128
// 默认是 = ，长度为32，后续调整长度
const uint8_t VtorStringPlayer_toneLenArray[] = {".,:;!=#@"};

// 塞入音调下标和长度，自动整理成字符串
uint8_t* VtorStringPlayer_PushTone(uint8_t* str, int8_t toneIdx, int16_t toneLen)
{
	// 先计算长度，如果0，就是0
	if(toneIdx < 1)
	{
		*str++ = '0';
	}
	else if(toneIdx < 1 + 7)
	{
		*str++ = '-';
		*str++ = (toneIdx - 1) + '1';
	}
	else if(toneIdx < 1 + 7 + 7)
	{
		*str++ = (toneIdx - 1 - 7) + '1';
	}
	else if(toneIdx < 1 + 7 + 7 + 7)
	{
		*str++ = '+';
		*str++ = (toneIdx - 1 - 7 - 7) + '1';
	}
	
	int i = 7;
	for(	; i > 0; i--)
	{
		if(toneLen & (1 << i))
		{
			*str++ = VtorStringPlayer_toneLenArray[i];
		}
	}
	
	*str = '\0';
	return str;
}

// 获取音调频率下标
int8_t VtorStringPlayer_GetToneIdx(VtorStringPlayer* player)
{
	uint8_t toneIdx = 1 + 7; // 中音1下标
	while(*(player->curMusicChar))
	{
		uint8_t curChar = *(player->curMusicChar);

		// 如果已有音调，且此时为数字，
		// 得知音调“6”“+1”“++5”“-5”等，
		// 由“+-”或数字开头
		if('0' == curChar)
		{
			toneIdx = 0;
			break;
			// 0做特殊处理，直接结束，不再判断
		}
		// 调整低音和高音
		toneIdx -= ('-' == curChar) ? 7 : 0;
		toneIdx += ('+' == curChar) ? 7 : 0;
		
		// 0代表静音，1~7代表不同音调
		if('1' <= curChar && curChar <= '7')
		{
			toneIdx += (curChar - '1');
			break;
		}
		// while内每次循环只处理1个字符
		player->curMusicChar++;
	}
	// 返回之前，调整，使其指向下一个音符
	player->curMusicChar++;
	// 如果数组越界，回到静音状态
	if(toneIdx > (1 + 3 * 7 - 1))
	{
		toneIdx = 0;
	}
	return toneIdx;
}


// 获取音调长度
int16_t VtorStringPlayer_GetToneLen(VtorStringPlayer* player)
{
	int16_t toneLen = 0; // 基本长度
	while(*(player->curMusicChar))
	{
		int8_t i = 0;
		uint8_t curChar = *(player->curMusicChar);

		for( ; VtorStringPlayer_toneLenArray[i] != '\0'; i++)
		{
			if(curChar == VtorStringPlayer_toneLenArray[i])
			{
				toneLen += 1 << i;
				break;
			}
		}
		if('\0' == VtorStringPlayer_toneLenArray[i])
		{
			// 如果出现了不匹配，那么结束
			break;
		}
		// 指向下一个说明符
		player->curMusicChar++;
	}
	// 如果没有长度描述符，恢复成默认长度
	if(0 == toneLen)
	{
		toneLen = player->presetToneLen;
		// 如果静音，将长度默认为最短的1
		if(0 == player->toneIdx)
		{
			toneLen = 1;
		}
	}
	else
	{
		// 如果有长度描述符，以32作为基数，调整对应长度
		toneLen = toneLen * player->presetToneLen / 32;
	}
	// 长度描述符后面一定是频率描述符，所以不用移动
	return toneLen;
}


void VtorStringPlayer_Run(VtorStringPlayer* player)
{
	// 当前音调，当前音调长度，当前频率
	if (player->toneLen <= 0)
	{
		if('\0' == *(player->curMusicChar))
		{
			VtorStringPlayer_SwitchMusicCallback(player);
			player->curMusicChar = player->curMusic[0];
		}
		
		player->toneIdx = VtorStringPlayer_GetToneIdx(player);
		player->toneLen = VtorStringPlayer_GetToneLen(player);
		player->freq = VtorStringPlayer_toneArray[player->toneIdx];
		VtorStringPlayer_PlayFreq(player);

		//VtorPrintf("tone %d %d %d [%s]\r\n",
		//	player->toneIdx, player->freq, player->toneLen,
		//	player->curMusicChar);

	}
	player->toneLen--;
}

#endif // __VTOR_STRING_PLAYER__

